
package com.hlkj.pay.app.merchant.ext.impl.hnapay.handler;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.merchant.ext.dto.access.ChannelMerchantBusinessContext;
import com.hlkj.pay.app.merchant.ext.impl.hnapay.dto.HnapayConfig;
import com.hlkj.pay.app.merchant.ext.impl.hnapay.utils.RecepitUtil;
import com.hlkj.pay.dto.merchant.MerchantAccessDto;
import com.hlkj.pay.dto.merchant.MerchantWechatConfigDto;
import com.hlkj.pay.infrastructure.model.merchant.*;
import com.hlkj.pay.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.DatePattern;
import org.springframework.util.StringUtils;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 汇付 商户进件参数处理
 * 
 * @author HlpayTeam
 * @date 2024/09/26 12:02
 */
@Slf4j
public class HnapayMerchantParamsHandle {

    /**
     *  支付宝报备
     *
     * @param channelMerchantBusinessContext
     * @return
     */
    public static CommonResult<Map<String, String>> alipayApplyParams(ChannelMerchantBusinessContext channelMerchantBusinessContext, HnapayConfig payConfig) throws Exception {
        MerchantAccessDto merchantAccessDto = channelMerchantBusinessContext.getMerchantAccessDto();
        MerchantAccessInfoDO merchantAccessInfo = merchantAccessDto.getMerchantAccessInfo();
        MerchantAccessBusinessDO merchantAccessBusiness = merchantAccessDto.getMerchantAccessBusiness();
        MerchantAccessLicenseDO merchantAccessLicenseDO = merchantAccessDto.getMerchantAccessLicense();
        MerchantAccessCardDO merchantAccessCardDO = merchantAccessDto.getMerchantAccessCard();
        MerchantAccessCertInfoDO merchantAccessContact = merchantAccessDto.getMerchantAccessContact();
        MerchantAccessCertInfoDO merchantAccessLegal = merchantAccessDto.getMerchantAccessLegal();

        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("version", "2.0");
        bodyMap.put("tranCode", "RPT01");
        bodyMap.put("merId", payConfig.getMerId());
        bodyMap.put("merOrderId", merchantAccessInfo.getRequestId());
        bodyMap.put("submitTime", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));

        Map<String, String> msgMap = new LinkedHashMap<>();
        msgMap.put("merchantName", merchantAccessInfo.getName());
        msgMap.put("merchantShortName", merchantAccessInfo.getShortName());
        msgMap.put("servicePhone", merchantAccessBusiness.getServicePhone());
        msgMap.put("business", merchantAccessBusiness.getMcc());
        msgMap.put("merchantCode", merchantAccessBusiness.getAlipayMcc());
        msgMap.put("merchantCardNo", merchantAccessLicenseDO.getLicenseCode());
        msgMap.put("merchantCardType", "NATIONAL_LEGAL");
        msgMap.put("contactName", merchantAccessContact.getName());
        msgMap.put("contactMobile", merchantAccessContact.getPhone());
        msgMap.put("contactEmail", merchantAccessLegal.getOtherValue());
        msgMap.put("contactType", "LEGAL_PERSON");
        msgMap.put("contactCardNo", merchantAccessContact.getCertNo());
        msgMap.put("provinceCode", merchantAccessBusiness.getProvinceCode());
        msgMap.put("cityCode", merchantAccessBusiness.getCityCode());
        msgMap.put("districtCode", merchantAccessBusiness.getAreaCode());
        msgMap.put("address", merchantAccessBusiness.getAddress());
        msgMap.put("bankCardNo", merchantAccessCardDO.getCardNo());
        msgMap.put("bankCardName", merchantAccessCardDO.getName());
        msgMap.put("payChannelId", payConfig.getAliChannelCode());
        msgMap.put("payChannelName", payConfig.getAliChannelName());
        msgMap.put("bankBranchName", "");
        msgMap.put("notifyUrl", channelMerchantBusinessContext.getAsyncReturnUrl());
        msgMap.put("legalPersonName", merchantAccessLegal.getName());
        msgMap.put("legalPersonCertNo", merchantAccessLegal.getCertNo());
        log.info("新生支付宝报备请求明文:{}", JsonUtils.toJsonString(msgMap));

        bodyMap.put("msgCiphertext", RecepitUtil.encrpt(msgMap, payConfig.getHnaM2PublicKey()));
        bodyMap.put("signValue", RecepitUtil.sign(payConfig.getMchM2PrivateKey(), bodyMap));
        bodyMap.put("signType", "3");
        bodyMap.put("charset", "1");

        return CommonResult.success(bodyMap);
    }

    /**
     * 微信报备
     * @param channelMerchantBusinessContext
     * @param payConfig
     * @return
     * @throws Exception
     */
    public static CommonResult<Map<String, String>> wechatApplyParams(ChannelMerchantBusinessContext channelMerchantBusinessContext, HnapayConfig payConfig) throws Exception {
        MerchantAccessDto merchantAccessDto = channelMerchantBusinessContext.getMerchantAccessDto();
        MerchantAccessInfoDO merchantAccessInfo = merchantAccessDto.getMerchantAccessInfo();
        MerchantAccessBusinessDO merchantAccessBusiness = merchantAccessDto.getMerchantAccessBusiness();
        MerchantAccessLicenseDO merchantAccessLicenseDO = merchantAccessDto.getMerchantAccessLicense();
        MerchantAccessCardDO merchantAccessCardDO = merchantAccessDto.getMerchantAccessCard();
        MerchantAccessCertInfoDO merchantAccessLegal = merchantAccessDto.getMerchantAccessLegal();

        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("version", "2.0");
        bodyMap.put("tranCode", "RPT03");
        bodyMap.put("merId", payConfig.getMerId());
        bodyMap.put("merOrderId", merchantAccessInfo.getRequestId());
        bodyMap.put("submitTime", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));

        Map<String, String> msgMap = new LinkedHashMap<>();
        msgMap.put("merchantName", merchantAccessInfo.getName());
        msgMap.put("merchantShortName", merchantAccessInfo.getShortName());
        msgMap.put("servicePhone", merchantAccessBusiness.getServicePhone());
        msgMap.put("business", merchantAccessBusiness.getWechatMcc());
        msgMap.put("payChannelId", payConfig.getWxChannelCode());
        msgMap.put("payChannelName", payConfig.getWxChannelName());
        msgMap.put("subAppId", "");
        msgMap.put("merchantCardNo", merchantAccessLicenseDO.getLicenseCode());
        msgMap.put("merchantCardType", "NATIONAL_LEGAL");
        msgMap.put("provinceCode", merchantAccessBusiness.getProvinceCode());
        msgMap.put("cityCode", merchantAccessBusiness.getCityCode());
        msgMap.put("districtCode", merchantAccessBusiness.getAreaCode());
        msgMap.put("address", merchantAccessBusiness.getAddress());
        msgMap.put("bankCardNo", merchantAccessCardDO.getCardNo());
        msgMap.put("bankCardName", merchantAccessCardDO.getName());
        msgMap.put("bankBranchName", "");
        msgMap.put("serviceCodes", "JSAPI,APP,APPLET,MICROPAY");
        msgMap.put("notifyUrl", channelMerchantBusinessContext.getAsyncReturnUrl());
        msgMap.put("legalPersonName", merchantAccessLegal.getName());
        msgMap.put("legalPersonCertNo", merchantAccessLegal.getCertNo());
        log.info("新生微信报备请求明文:{}", JsonUtils.toJsonString(msgMap));

        bodyMap.put("msgCiphertext", RecepitUtil.encrpt(msgMap, payConfig.getHnaM2PublicKey()));
        bodyMap.put("signValue", RecepitUtil.sign(payConfig.getMchM2PrivateKey(), bodyMap));
        bodyMap.put("signType", "3");
        bodyMap.put("charset", "1");

        return CommonResult.success(bodyMap);
    }

    /**商户报备状态查询*/
    public static CommonResult<Map<String, String>> queryApplyStatus(String requestId, HnapayConfig payConfig) throws Exception {
        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("version", "2.0");
        bodyMap.put("tranCode", "RPT02");
        bodyMap.put("merId", payConfig.getMerId());
        bodyMap.put("merOrderId", requestId);
        bodyMap.put("reportedNo", requestId);
        bodyMap.put("submitTime", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        bodyMap.put("signValue", RecepitUtil.sign(payConfig.getMchM2PrivateKey(), bodyMap));
        bodyMap.put("signType", "3");
        bodyMap.put("charset", "1");
        return CommonResult.success(bodyMap);
    }

    /**微信初始化配置*/
    public static CommonResult<Map<String, String>> wxConfigInit(HnapayConfig payConfig, MerchantAccessAuthDO merchantAccessAuth, String appId, String path) throws Exception {
        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("version", "2.0");
        if (StringUtils.hasText(appId))
            bodyMap.put("tranCode", "RPT05");
        else
            bodyMap.put("tranCode", "RPT06");
        bodyMap.put("merId", payConfig.getMerId());
        bodyMap.put("merOrderId", DateUtils.getCurrentTime().toString());
        bodyMap.put("reportedNo", merchantAccessAuth.getSerialCode());
        if (StringUtils.hasText(appId))
            bodyMap.put("appId", appId);
        else
            bodyMap.put("jsapiPath", path);
        bodyMap.put("submitTime", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        bodyMap.put("signValue", RecepitUtil.sign(payConfig.getMchM2PrivateKey(), bodyMap));
        bodyMap.put("signType", "3");
        bodyMap.put("charset", "1");
        return CommonResult.success(bodyMap);
    }

    /**微信配置*/
    public static CommonResult<Map<String, String>> wxConfig(ChannelMerchantBusinessContext channelMerchantBusinessContext, HnapayConfig payConfig, MerchantAccessAuthDO merchantAccessAuth) throws Exception {
        MerchantWechatConfigDto merchantWechatConfigDto = channelMerchantBusinessContext.getMerchantWechatConfigDto();
        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("version", "2.0");
        if (StringUtils.hasText(merchantWechatConfigDto.getAppId()))
            bodyMap.put("tranCode", "RPT05");
        else
            bodyMap.put("tranCode", "RPT06");
        bodyMap.put("merId", payConfig.getMerId());
        bodyMap.put("merOrderId", DateUtils.getCurrentTime().toString());
        bodyMap.put("reportedNo", merchantAccessAuth.getSerialCode());
        if (StringUtils.hasText(merchantWechatConfigDto.getAppId()))
            bodyMap.put("appId", merchantWechatConfigDto.getAppId());
        else
            bodyMap.put("jsapiPath", merchantWechatConfigDto.getJsAPIPath());
        bodyMap.put("submitTime", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        bodyMap.put("signValue", RecepitUtil.sign(payConfig.getMchM2PrivateKey(), bodyMap));
        bodyMap.put("signType", "3");
        bodyMap.put("charset", "1");
        return CommonResult.success(bodyMap);
    }

    /**微信配置查询*/
    public static CommonResult<Map<String, String>> wxConfigQuery(HnapayConfig payConfig, MerchantAccessAuthDO merchantAccessAuth) throws Exception {
        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("version", "2.0");
        bodyMap.put("tranCode", "RPT07");
        bodyMap.put("merId", payConfig.getMerId());
        bodyMap.put("merOrderId", DateUtils.getCurrentTime().toString());
        bodyMap.put("reportedNo", merchantAccessAuth.getSerialCode());
        bodyMap.put("submitTime", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        bodyMap.put("signValue", RecepitUtil.sign(payConfig.getMchM2PrivateKey(), bodyMap));
        bodyMap.put("signType", "3");
        bodyMap.put("charset", "1");
        return CommonResult.success(bodyMap);
    }

    /**支付宝/微信 认证授权查询*/
    public static CommonResult<Map<String, String>> authQuery(HnapayConfig payConfig, MerchantAccessAuthDO merchantAccessAuth) throws Exception {
        Map<String, String> bodyMap = new LinkedHashMap<>();
        bodyMap.put("version", "2.0");
        bodyMap.put("tranCode", "RPT04");
        bodyMap.put("merId", payConfig.getMerId());
        bodyMap.put("merOrderId", DateUtils.getCurrentTime().toString());
        bodyMap.put("reportedNo", merchantAccessAuth.getSerialCode());
        bodyMap.put("submitTime", DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        bodyMap.put("signValue", RecepitUtil.sign(payConfig.getMchM2PrivateKey(), bodyMap));
        bodyMap.put("signType", "3");
        bodyMap.put("charset", "1");
        return CommonResult.success(bodyMap);
    }

}
